package servlet;

import java.io.IOException;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import toolkit.Debug;
import bean.AbstractBean;
import domain.PizzaManager;

abstract public class AbstractStepServlet extends AbstractServlet
{
	private static final long serialVersionUID = 1L;
	
	protected HttpServletRequest request;
	
	protected HttpServletResponse response;
	
	protected PizzaManager pizzaManager;
	
	protected HttpSession session;
	
	protected String method;
	
	private void initDispatch(HttpServletRequest request, HttpServletResponse response, String method)
	{
		Debug.log("(" + id + ") " + className + ".initDispatch()");
		
		this.request = request;
		
		this.response = response;
		
		this.method = method;
		
		pizzaManager = getPizzaManager(request, response);
		
		session = getSession(request, response);
	}
	
	// Is called before the any dispatch method.
	public void preDispatch()
	{
		Debug.log("(" + id + ") " + className + ".preDispatch()");
	}
	
	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		Debug.log("(" + id + ") " + className + ".doGet()");
		
		initDispatch(request, response, "get");
		
		if (checkStep())
		{
			preDispatch();
			
			dispatchGet();
		}
	}
	
	abstract void dispatchGet() throws ServletException, IOException;
	
	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		Debug.log("(" + id + ") " + className + ".doPost()");
		
		initDispatch(request, response, "post");
		
		Debug.log("(" + id + ") step name = " + name);
		
		if (checkStep())
		{
			preDispatch();
			
			dispatchPost();
		}
	}
	
	abstract void dispatchPost() throws ServletException, IOException;
	
	protected boolean checkStep() throws IOException
	{
		Debug.log("(" + id + ") " + className + ".checkStep(" + request + ", " + response + ")");
		
		Debug.log("(" + id + ") step name = " + name);
		
		int step = steps.indexOf(name);
		
		Debug.log("(" + id + ") step = " + step);
		
		// Get the previous step.
		Integer stepAttribute = (Integer) session.getAttribute("step");
		
		int currentStep = stepAttribute != null ? stepAttribute.intValue() : 0;
		
		Debug.log("(" + id + ") current step = " + currentStep);
		
		// You may not skip steps.
		if (step != currentStep && step != 0)
		{
			// Go to the previous page if you tried to skip one.			
			redirect(steps.get(currentStep));
			
			Debug.log("(" + id + ") SKIP STAP");
			
			return false;
		}
		
		Debug.log("(" + id + ") CONTINUE STAP");
		
		request.setAttribute("step", step);
		
		return true;
	}
	
	protected void redirectNextStep() throws IOException
	{
		Debug.log("(" + id + ") " + className + ".redirectNextStep()");
		
		int step = nextStep();
		
		redirect(steps.get(step));
	}
	
	protected int nextStep()
	{
		Debug.log("(" + id + ") " + className + ".nextStep()");
		
		int step = steps.indexOf(name);
		
		Debug.log("---------------------------");
		Debug.log("step:" + step + " size:" + (steps.size() - 1));
		
		if (step == -1 || step == steps.size() - 1)
		{
			step = 0;
		}
		else
		{
			step++;
		}
		
		Debug.log("---------------------------");
		Debug.log("step:" + step + " size:" + (steps.size() - 1));
		
		Debug.log("---------------------------");
		
		session.setAttribute("step", new Integer(step));
		
		return step;
	}
	
	public void resetStep()
	{
		session.setAttribute("step", new Integer(0));
	}
	
	protected void redirect(String name) throws IOException
	{
		Debug.log("(" + id + ") " + className + ".redirect(" + name + ")");
		//response.sendRedirect("/Pizza/" + name);
		response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
		response.setHeader("Location", "/Pizza/" + name);
	}
	
	protected void display() throws ServletException, IOException
	{
		Debug.log("(" + id + ") " + className + ".forward(" + request + ", " + response + ")");
		
		display(name);
	}
	
	protected void display(String name) throws ServletException, IOException
	{
		Debug.log("(" + id + ") " + className + ".display(" + request + ", " + response + ", " + name + ")");
		
		/*int step = steps.indexOf(name);
		
		String name = this.name;
		
		// If the servlet is not found...
		if (step == -1)
		{
			// ... go to the first page.
			step = 0;
			
			name = steps.get(step);
		}*/

		RequestDispatcher dispatcher = request.getRequestDispatcher("/jsp/Page/" + name + ".jsp");
		dispatcher.forward(request, response);
	}
	
	public Cookie getCookie(String name)
	{
		return super.getCookie(name, request);
	}
	
	public Map<String, Object> getPostValues()
	{
		return super.getPostValues(request);
	}
	
	public AbstractBean getPostValuesBean()
	{
		AbstractBean bean = getBean();
		
		if (bean != null)
		{
			bean.populate(getPostValues(request));
		}
		
		return bean;
	}
}
